package com.gsoc.spreadsheet.client;

/**
 * An abstract representation of a cell in the grid.
 */
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class DataCell extends Widget implements CellRPCAsync, ClickListener {

	/**
	 * The data this cell contains
	 */
	private Double data;
	
	/**
	 * The cell's x and y coordinates in its cluster
	 */
	private int x, y;
	
	/**
	 * The textbox that ultimately represents the cell in the UI
	 */
	private TextBox text = new TextBox();
	
	/**
	 * The type of class to look for on the server-side for RPCs
	 */
	private CellRPCAsync service = (CellRPCAsync) GWT.create(CellRPC.class);
	
	/**
	 * Where on the server to look for the above class
	 */
	private ServiceDefTarget endpoint = (ServiceDefTarget) service;

	/**
	 * Class constructor
	 * 
	 * @param newX	the x coordinate for this DataCell
	 * @param newY	the y coordinate for this DataCell
	 */
	public DataCell(int newX, int newY) {
		x = newX;
		y = newY;
		endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");
		
		getServerData(x, y, new AsyncCallback() {
			public void onSuccess(Object result) {
				data = (Double)result;
				text.setText(data + "");
			}
			
			public void onFailure(Throwable caught) {
				return;
			}
		});
	
		text.addClickListener(this);
	}
	
	/**
	 * Class constructor
	 * 
	 * @param newX	the x coordinate for this DataCell
	 * @param newY	the y coordinate for this DataCell
	 * @param input	the data this cell will contain
	 */
	public DataCell(int newX, int newY, Double input) {
		x = newX;
		y = newY;
		endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");
		data = input;
		
		text.setText(data + "");
		text.addClickListener(this);
	}
	
	/**
	 * 
	 * @return	The data in this cell
	 */
	public Double getData() { return data; }
	
	/**
	 * 
	 * @return	This cell's x coordinate within its cluster
	 */
	public int getX() { return x; }
	
	/**
	 * 
	 * @return	This cell's y coordinate within its cluster
	 */
	public int getY() {	return y; }
	
	/**
	 * 
	 * @return	A TextBox representing this DataCell
	 */
	public TextBox view() {
		return text;
	}
	
	/**
	 * Set the data for this cell
	 * @param input	The new data for this cell
	 */
	public void setData(Double input) {
		data = input;
		text.setText(data + "");
	}
	
	/**
	 * Change the text in the textbox. Used for outputting errors.
	 * 
	 * @param input	The text to put in the textbox
	 */
	public void setText(String input) {
		text.setText(input);
	}
	
	/**
	 * 
	 * @param newX	The new X coordinate for this DataCell
	 */
	public void setX(int newX) {
		x = newX;
	}
	
	/**
	 * 
	 * @param newY	The new Y coordinate for this DataCekk
	 */
	public void setY(int newY) {
		y = newY;
	}
	
	/**
	 * Retrieve data from the server for this cell
	 */
	public void getServerData(int x, int y, AsyncCallback callback) {
		service.getServerData(x, y, callback);
	}
	
	public boolean equals(DataCell other) {
		if(other.getData().equals(data))
			return true;
		else return false;
	}
	
	/**
	 * 
	 */
	public void onClick(Widget sender) {
		if(sender == this) {
			Window.alert("You clicked cell (" + x + ", " + y + ")!");
		}
	}
	
}